From 588152f10da42be093d7ab0f41809898975fd6ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Caol=C3=A1n=20McNamara?= Date: Sun, 12 Jul 2026 16:09:48 +0000 Subject: [PATCH] [PATCH] firebird: don't attach a database that is not in the normal backup state MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A database we extract from a .odb is always in the normal backup state, so refuse one that is not, we're not interested in the difference file mode case. firebird upstream attempt as: https://github.com/FirebirdSQL/firebird/pull/9089 And do it manually for the system-firebird case. Change-Id: Iff9ebbb075379ca47a7f7f5886b693ac23860566 Signed-off-by: Caolán McNamara Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6702 Reviewed-by: Miklos Vajna Tested-by: Jenkins CPCI (cherry picked from commit e7ea381e87cadaf31bf1ad2213a23f17a6284d1c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208040 Reviewed-by: Xisco Fauli Tested-by: Xisco Fauli Signed-off-by: Xisco Fauli Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208064 Tested-by: Jenkins Signed-off-by: Xisco Fauli Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208076 Signed-off-by: Xisco Fauli Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208112 Tested-by: Christian Lohmaier Reviewed-by: Hossein Reviewed-by: Christian Lohmaier Gbp-Pq: Name CVE-2026-63266-3.diff --- .../source/drivers/firebird/Connection.cxx | 42 +++++++++++++++++ external/firebird/UnpackedTarball_firebird.mk | 1 + ...rebird-nbak-difference-file-access.patch.1 | 47 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 external/firebird/firebird-nbak-difference-file-access.patch.1 diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index dad99cd50b8..c5e1e958af6 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -120,6 +120,39 @@ struct ConnectionGuard } }; +// A set nbackup state makes firebird open a difference file +// (BackupManager::actualizeState and openDelta, firebird/src/jrd/nbak.cpp). +// A database we made is never in that state, so refuse it. +bool databaseHeaderHasBackupState(const OUString& rDatabasePath) +{ + OUString sFileURL; + if (::osl::FileBase::getFileURLFromSystemPath(rDatabasePath, sFileURL) != ::osl::FileBase::E_None) + return false; + + ::osl::File aFile(sFileURL); + if (aFile.open(osl_File_OpenFlag_Read) != ::osl::FileBase::E_None) + return false; + + // Ods::header_page, firebird/src/jrd/ods.h + sal_uInt8 aHeader[44]; + sal_uInt64 nRead = 0; + ::osl::FileBase::RC eRead = aFile.read(aHeader, sizeof(aHeader), nRead); + aFile.close(); + + if (eRead != ::osl::FileBase::E_None || nRead < sizeof(aHeader)) + return false; + + // pag_type, Ods::pag_header + const sal_uInt8 nPageTypeHeader = 1; + if (aHeader[0] != nPageTypeHeader) + return false; + + // hdr_flags & hdr_backup_mask, normal state is 0 + const sal_uInt16 nFlags = aHeader[42] | (aHeader[43] << 8); + const sal_uInt16 nBackupStateMask = 0x0C00; + return (nFlags & nBackupStateMask) != 0; +} + } void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info, @@ -184,6 +217,15 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& SAL_INFO("connectivity.firebird", "Found .fdb instead of .fbk"); bIsFdbStored = true; loadDatabaseFile(our_sFDBLocation, m_sFirebirdURL); + // Decline a database whose header asks firebird to use a + // difference file + if (databaseHeaderHasBackupState(m_sFirebirdURL)) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst( + "$filename$", m_sConnectionURL); + ::dbtools::throwGenericSQLException(sMessage, *this); + } } else { diff --git a/external/firebird/UnpackedTarball_firebird.mk b/external/firebird/UnpackedTarball_firebird.mk index 821b167650d..bd802c6f18b 100644 --- a/external/firebird/UnpackedTarball_firebird.mk +++ b/external/firebird/UnpackedTarball_firebird.mk @@ -31,6 +31,7 @@ $(eval $(call gb_UnpackedTarball_update_autoconf_configs,firebird,\ # at "extern/cloop: Missing dependencies of # compilations on output directories": $(eval $(call gb_UnpackedTarball_add_patches,firebird,\ + external/firebird/firebird-nbak-difference-file-access.patch.1 \ external/firebird/firebird.disable-ib-util-not-found.patch.1 \ external/firebird/firebird-Engine12.patch \ external/firebird/firebird-rpath.patch.0 \ diff --git a/external/firebird/firebird-nbak-difference-file-access.patch.1 b/external/firebird/firebird-nbak-difference-file-access.patch.1 new file mode 100644 index 00000000000..256d805e8f1 --- /dev/null +++ b/external/firebird/firebird-nbak-difference-file-access.patch.1 @@ -0,0 +1,47 @@ +Verify difference file path against DatabaseAccess + +The difference file opened in openDelta and beginBackup was not verified +against DatabaseAccess like the other database file paths. + +Submitted upstream as https://github.com/FirebirdSQL/firebird/pull/9089 + +--- firebird/src/jrd/nbak.cpp ++++ firebird/src/jrd/nbak.cpp +@@ -35,6 +35,7 @@ + #include "lck.h" + #include "cch.h" + #include "lck_proto.h" ++#include "jrd_proto.h" + #include "pag_proto.h" + #include "err_proto.h" + #include "cch_proto.h" +@@ -224,6 +225,14 @@ + void BackupManager::openDelta(thread_db* tdbb) + { + fb_assert(!diff_file); ++ ++ // Verify difference file path against DatabaseAccess entry of firebird.conf ++ if (!JRD_verify_database_access(diff_name)) ++ { ++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") << ++ Arg::Str(diff_name)); ++ } ++ + diff_file = PIO_open(tdbb, diff_name, diff_name); + + if (database->dbb_flags & (DBB_force_write | DBB_no_fs_cache)) +@@ -283,6 +292,14 @@ + { + // Create file + NBAK_TRACE(("Creating difference file %s", diff_name.c_str())); ++ ++ // Verify difference file path against DatabaseAccess entry of firebird.conf ++ if (!JRD_verify_database_access(diff_name)) ++ { ++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") << ++ Arg::Str(diff_name)); ++ } ++ + diff_file = PIO_create(tdbb, diff_name, true, false); + } + catch (const Firebird::Exception&) -- 2.39.5